﻿using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace SnapDesktop
{
    internal class SnapSelector : Form
    {
        //Class Settings (Can be changed)
        private readonly SnapApplication _snap;
        public Color OverlayColor = Color.Black;
        public double OverlayOpacity = 0.20;
        public Color TransparancyColor = Color.Green;

        private bool _selectionFinished;
        private bool _selectionStarted;
        private Point _startLocation;

        public SnapSelector(SnapApplication snap)
        {
            _snap = snap;
            Visible = false; //Stops Flashing during setup
            Setup();
        }

        public void Setup()
        {
            //Setup Form Settings
            TopMost = true;
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
            ShowInTaskbar = false;
            FormBorderStyle = FormBorderStyle.None;

            //Setup Form Style
            BackColor = OverlayColor;
            TransparencyKey = TransparancyColor;
            Opacity = OverlayOpacity;

            //Setup Event handlers
            MouseDown += OnMouseDown;
            MouseUp += OnMouseUp;
            KeyDown += OnKeyDown;
            Load += LoadWindow;
        }

        private void LoadWindow(object sender, EventArgs e)
        {
            if (!Visible)
            {
                Visible = true; //Restore Visibility
            }
            //Multiple Desktop Support
            var rect = new Rectangle();
            rect = Screen.AllScreens.Aggregate(rect, (current, s) => Rectangle.Union(current, s.Bounds));
            var corner = new Point(rect.X, rect.Y);
            Size = new Size(rect.Width, rect.Height);
            Location = corner;
        }


        //Draw
        protected override void OnPaint(PaintEventArgs e)
        {
            int x = Cursor.Position.X;
            int y = Cursor.Position.Y;

            var selectionStart = new Point(0, 0);

            if (_selectionStarted)
            {
                if (x < _startLocation.X && y > _startLocation.Y)
                {
                    selectionStart.X = x;
                    selectionStart.Y = _startLocation.Y;
                }
                else if (x < _startLocation.X && y < _startLocation.Y)
                {
                    selectionStart.X = x;
                    selectionStart.Y = y;
                }
                else if (x > _startLocation.X && y < _startLocation.Y)
                {
                    selectionStart.X = _startLocation.X;
                    selectionStart.Y = y;
                }
                else
                {
                    selectionStart.X = _startLocation.X;
                    selectionStart.Y = _startLocation.Y;
                }

                var selectionSize = new Size(Math.Abs(x - _startLocation.X), Math.Abs(y - _startLocation.Y));
                selectionStart = PointToClient(selectionStart);

                if (_selectionFinished)
                {
                    _snap.SnapArea = new Rectangle(PointToScreen(selectionStart), selectionSize);
                    Dispose();
                }
                else
                {
                    e.Graphics.FillRectangle(Brushes.White, new Rectangle(selectionStart, selectionSize));
                }
            }

            Invalidate(); //cause redraw
        }

        private void OnMouseDown(object sender, MouseEventArgs e)
        {
            _selectionStarted = true;
            _startLocation = Cursor.Position;
        }

        private void OnMouseUp(object sender, MouseEventArgs e)
        {
            _selectionFinished = true;
        }

        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Escape) return;
            _snap.Canceled = true;
            Dispose();
        }
    }
}